/*
This file is part of Arcadeflex.

Arcadeflex is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Arcadeflex is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Arcadeflex.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * ported to v0.28
 * ported to v0.27
 *
 *
 *   roms are from mame 0.36 romset
 */

package drivers;
import static arcadeflex.libc.*;
import static mame.commonH.*;
import static mame.cpuintrf.*;
import static mame.driverH.*;
import static mame.mame.*;
import static mame.inptport.*;
import static mame.osdependH.*;
import static sndhrdw._8910intf.*;
import static sndhrdw.popeye.*;
import static vidhrdw.generic.*;
import static vidhrdw.popeye.*;

public class popeye
{



	static MemoryReadAddress readmem[] =
	{
		new MemoryReadAddress( 0x8000, 0x87ff, MRA_RAM ),
		new MemoryReadAddress( 0x8c00, 0x8e7f, MRA_RAM ),
		new MemoryReadAddress( 0x8f00, 0x8fff, MRA_RAM ),
		new MemoryReadAddress( 0x0000, 0x7fff, MRA_ROM ),
		new MemoryReadAddress( -1 )	/* end of table */
	};
	
	static MemoryWriteAddress writemem[] =
	{
		new MemoryWriteAddress( 0x8000, 0x87ff, MWA_RAM ),
		new MemoryWriteAddress( 0x8c04, 0x8e7f, MWA_RAM, spriteram,spriteram_size ),
		new MemoryWriteAddress( 0x8f00, 0x8fff, MWA_RAM ),
		new MemoryWriteAddress( 0xa000, 0xa3ff, videoram_w, videoram, videoram_size  ),
		new MemoryWriteAddress( 0xa400, 0xa7ff, colorram_w, colorram ),
		new MemoryWriteAddress( 0xc000, 0xcfff, popeye_videoram_w, popeye_videoram, popeye_videoram_size ),
		new MemoryWriteAddress( 0x8c00, 0x8c01, MWA_RAM, popeye_background_pos ),
		new MemoryWriteAddress( 0x8c03, 0x8c03, popeye_palettebank_w, popeye_palette_bank ),
		new MemoryWriteAddress( 0x0000, 0x7fff, MWA_ROM ),
		new MemoryWriteAddress( -1 )	/* end of table */
	};
	
	
	
	static IOReadPort readport[] =
	{
		new IOReadPort( 0x00, 0x00, input_port_0_r ),
		new IOReadPort( 0x01, 0x01, input_port_1_r ),
		new IOReadPort( 0x02, 0x02, input_port_2_r ),
		new IOReadPort( 0x03, 0x03, AY8910_read_port_0_r ),
		new IOReadPort( -1 )	/* end of table */
	};
	
	static IOWritePort writeport[] =
	{
		new IOWritePort( 0x00, 0x00, AY8910_control_port_0_w ),
		new IOWritePort( 0x01, 0x01, AY8910_write_port_0_w ),
		new IOWritePort( -1 )	/* end of table */
	};
	
	
	
	
	
	static InputPort input_ports[] =
	{
		new InputPort(	/* IN0 */
			0x00,
			new int[] { OSD_KEY_RIGHT, OSD_KEY_LEFT, OSD_KEY_UP, OSD_KEY_DOWN,
					OSD_KEY_CONTROL, OSD_KEY_E, OSD_KEY_Q, OSD_KEY_W }
		),
		new InputPort(	/* IN1 */
			0x00,
			new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }
		),
		new InputPort(	/* IN2 */
			0x00,
			new int[] { OSD_KEY_8, OSD_KEY_9, OSD_KEY_1,OSD_KEY_2,
	                      OSD_KEY_0, OSD_KEY_5, OSD_KEY_4,OSD_KEY_3 }
		),
		new InputPort(	/* DSW1 */
			0x3f,
			new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }
		),
		new InputPort(	/* DSW2 */
			0x3d,
			new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }
		),
		new InputPort( -1 )	/* end of table */
	};
	static TrakPort[] trak_ports =
       {
           new TrakPort(-1)
       };

      static KEYSet[] keys =
      {
          new KEYSet(0, 2, "MOVE UP"),
          new KEYSet(0, 1, "MOVE LEFT"   ),
          new KEYSet(0, 0, "MOVE RIGHT"),
          new KEYSet( 0, 3, "MOVE DOWN" ),
          new KEYSet(0, 4, "FIRE1"),
          new KEYSet(0, 6, "FIRE2" ),
          new KEYSet(0, 7, "FIRE3" ),
          new KEYSet(0, 5, "FIRE4"),
          new KEYSet(-1) };

	
	static DSW dsw[] =
	{
		new DSW( 4, 0x03, "LIVES", new String[] { "4", "3", "2", "1" }, 1 ),
		new DSW( 4, 0x30, "BONUS", new String[] { "NONE", "80000", "60000", "40000" }, 1 ),
		new DSW( 4, 0x0c, "DIFFICULTY", new String[] { "HARDEST", "HARD", "MEDIUM", "EASY" }, 1 ),
		new DSW( 4, 0x40, "DEMO SOUNDS", new String[] { "ON", "OFF" }, 1 ),
		new DSW( 3, 0x10, "SW1 5", new String[] { "ON", "OFF" }, 1 ),
		new DSW( 3, 0x20, "SW1 6", new String[] { "ON", "OFF" }, 1 ),
		new DSW( -1 )
	};
	
	
	
	static GfxLayout charlayout = new GfxLayout
	(
		16,16,	/* 16*16 characters (8*8 doubled) */
		256,	/* 256 characters */
		1,	/* 1 bit per pixel (there are two bitplanes in the ROM, but only one is used) */
		new int[] { 0 },
		new int[] { 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1, 0,0 },	/* pretty straightforward layout */
		new int[] { 0*8,0*8, 1*8,1*8, 2*8,2*8, 3*8,3*8, 4*8,4*8, 5*8,5*8, 6*8,6*8, 7*8,7*8 },
		8*8	/* every char takes 8 consecutive bytes */
	);
	static GfxLayout spritelayout = new GfxLayout
	(
		16,16,	/* 16*16 sprites */
		256,	/* 256 sprites */
		2,	/* 2 bits per pixel */
		new int[] { 0, 0x4000*8 },	/* the two bitplanes are separated in different files */
		new int[] {7+(0x2000*8),6+(0x2000*8),5+(0x2000*8),4+(0x2000*8),
	     3+(0x2000*8),2+(0x2000*8),1+(0x2000*8),0+(0x2000*8),
	   7,6,5,4,3,2,1,0 },
		new int[] { 15*8, 14*8, 13*8, 12*8, 11*8, 10*8, 9*8, 8*8,
	    7*8, 6*8, 5*8, 4*8, 3*8, 2*8, 1*8, 0*8, },
		16*8	/* every sprite takes 16 consecutive bytes */
	);
	/* there's nothing here, this is just a placeholder to let the video hardware */
	/* pick the background color table. */
	static GfxLayout fakelayout = new GfxLayout
	(
		1,1,
		0,
		1,
		new int[] { 0 },
		new int[] { 0 },
		new int[] { 0 },
		0
	);
	
	
	
	static GfxDecodeInfo gfxdecodeinfo[] =
	{
		new GfxDecodeInfo( 1, 0x0800, charlayout,        0, 32 ),	/* chars */
		new GfxDecodeInfo( 1, 0x1000, spritelayout,32*2+32, 64 ),	/* sprites */
		new GfxDecodeInfo( 1, 0x2000, spritelayout,32*2+32, 64 ),	/* sprites */
		new GfxDecodeInfo( 0, 0,      fakelayout,     32*2, 32 ),	/* background bitmap */
		new GfxDecodeInfo( -1 ) /* end of array */
	};
	
	
	
	static char color_prom[] =
	{
		/* char palette */
		0x78,0xF0,0xF6,0xA4,0x07,0xD0,0x2F,0xAD,0xFF,0x36,0x3F,0x73,0xFF,0xAF,0xD0,0x00,
		0x78,0xF0,0xF6,0xA4,0x07,0xD0,0x2F,0xAD,0xFF,0x36,0x3F,0x73,0xFF,0xAF,0xD0,0x00,
		/* background palette */
		0x00,0x0A,0x2A,0x01,0x15,0x27,0x05,0x5B,0x40,0x48,0x9B,0xAE,0x54,0x53,0xB7,0x4D,
		0x00,0x89,0x05,0x40,0xFF,0x0F,0x01,0x16,0x00,0x0B,0xB7,0x2F,0x03,0x07,0xED,0xFF,
		/* sprite palette */
		/* low 4 bits */
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0A,0x00,0x07,0x0F,0x00,
		0x00,0x07,0x0F,0x08,0x00,0x0C,0x07,0x00,0x00,0x06,0x08,0x00,0x00,0x03,0x0F,0x04,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0B,0x00,0x07,0x0F,0x0F,
		0x00,0x07,0x06,0x06,0x00,0x04,0x06,0x00,0x00,0x06,0x08,0x00,0x00,0x0C,0x0F,0x0F,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0B,0x00,0x07,0x0F,0x08,
		0x00,0x08,0x00,0x0F,0x00,0x02,0x0F,0x0F,0x00,0x06,0x08,0x00,0x00,0x02,0x0F,0x07,
		0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x05,0x0F,0x0F,0x00,0x07,0x00,0x07,
		0x00,0x07,0x0F,0x05,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0A,0x00,0x07,0x0F,0x00,
		0x00,0x07,0x0F,0x08,0x00,0x0C,0x07,0x00,0x00,0x06,0x08,0x00,0x00,0x03,0x0F,0x04,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0B,0x00,0x07,0x0F,0x0F,
		0x00,0x07,0x06,0x06,0x00,0x04,0x06,0x00,0x00,0x06,0x08,0x00,0x00,0x0C,0x0F,0x0F,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x07,0x0F,0x0B,0x00,0x07,0x0F,0x08,
		0x00,0x08,0x00,0x0F,0x00,0x02,0x0F,0x0F,0x00,0x06,0x08,0x00,0x00,0x02,0x0F,0x07,
		0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x05,0x0F,0x0F,0x00,0x07,0x00,0x07,
		0x00,0x07,0x0F,0x05,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,
		/* high 4 bits */
		0x00,0x00,0x00,0x00,0x00,0x08,0x0A,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x0A,
		0x00,0x00,0x0F,0x03,0x00,0x00,0x0B,0x0C,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x08,
		0x00,0x00,0x00,0x00,0x00,0x08,0x0A,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x0F,
		0x00,0x00,0x0F,0x03,0x00,0x01,0x0F,0x0C,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x01,
		0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x09,
		0x00,0x03,0x00,0x03,0x00,0x00,0x06,0x0F,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x04,
		0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x01,0x0A,0x0F,0x00,0x00,0x00,0x00,
		0x00,0x00,0x0A,0x01,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,
		0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x0A,
		0x00,0x00,0x0F,0x03,0x00,0x00,0x0B,0x0C,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x08,
		0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x0F,
		0x00,0x00,0x0F,0x03,0x00,0x01,0x0F,0x0C,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x01,
		0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x0F,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x09,
		0x00,0x03,0x00,0x03,0x00,0x00,0x06,0x0F,0x00,0x0F,0x03,0x0C,0x00,0x00,0x0A,0x04,
		0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x00,0x01,0x0A,0x0F,0x00,0x00,0x00,0x00,
		0x00,0x00,0x0A,0x01,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F,0x00,0x0F,0x0F,0x0F
	};
	
	
	
	static MachineDriver machine_driver = new MachineDriver
	(
		/* basic machine hardware */
		new MachineCPU[] {
			new MachineCPU(
				CPU_Z80,
				4000000,	/* 4 Mhz */
				0,
				readmem, writemem, readport, writeport,
				popeye_sh_interrupt,20
			)
		},
		30,
		null,
	
		/* video hardware */
		32*16, 30*16, new rectangle( 0*16, 32*16-1, 1*16, 29*16-1 ),
		gfxdecodeinfo,
		256, 32*2+32+64*4,
		popeye_vh_convert_color_prom,
                VIDEO_TYPE_RASTER,
		null,
		popeye_vh_start,
		popeye_vh_stop,
		popeye_vh_screenrefresh,

		/* sound hardware */
		null,
		null,
		popeye_sh_start,
		AY8910_sh_stop,
		AY8910_sh_update
	);
	
	
	
	/***************************************************************************
	
	  Game driver(s)
	
	***************************************************************************/
	static RomLoadPtr popeyebl_rom= new RomLoadPtr(){ public void handler() 
        {
	    ROM_REGION(0x10000);	/* 64k for code */
		ROM_LOAD("po1",          0x0000, 0x2000, 0xb14a07ca );
		ROM_LOAD("po2",          0x2000, 0x2000, 0x995475ff );
		ROM_LOAD("po3",          0x4000, 0x2000, 0x99d6a04a );
		ROM_LOAD("po4",          0x6000, 0x2000, 0x548a6514 );
		ROM_LOAD("po_d1-e1.bin", 0xe000, 0x0020, 0x8de22998 );	/* protection PROM */
	
	   ROM_REGION(0x9000);	/* temporary space for graphics (disposed after conversion) */
		ROM_LOAD("v-5n", 0x0000, 0x1000, 0xcca61ddd );
		ROM_LOAD("v-1e", 0x1000, 0x2000, 0x0f2cd853 );
		ROM_LOAD("v-1f", 0x3000, 0x2000, 0x888f3474 );
		ROM_LOAD("v-1j", 0x5000, 0x2000, 0x7e864668 );
		ROM_LOAD("v-1k", 0x7000, 0x2000, 0x49e1d170 );
                
	        ROM_END();
        }};
	

	
	
	static HiscoreLoadPtr hiload = new HiscoreLoadPtr() { public int handler(String name)
	{
		/* check if the hi score table has already been initialized */
		if (memcmp(RAM, 0x8209, new char[] { 0x00, 0x26, 0x03 }, 3) == 0 &&
				memcmp(RAM, 0x8221, new char[] { 0x50, 0x11, 0x02}, 3) == 0)
		{
			FILE f;
	
	
			if ((f = fopen(name, "rb")) != null)
			{
				int i;
	
	
				fread(RAM, 0x8200, 1, 6+6*5, f);
	
				i = RAM[0x8201];
	
				RAM[0x8fed] = RAM[0x8200+i-2];
				RAM[0x8fee] = RAM[0x8200+i-1];
				RAM[0x8fef] = RAM[0x8200+i];
	
				RAM[0x8f32] = (char) (RAM[0x8200+i] >> 4);
				RAM[0x8f33] = (char) (RAM[0x8200+i] & 0x0f);
				RAM[0x8f34] = (char) (RAM[0x8200+i-1] >> 4);
				RAM[0x8f35] = (char) (RAM[0x8200+i-1] & 0x0f);
				RAM[0x8f36] = (char) (RAM[0x8200+i-2] >> 4);
				RAM[0x8f37] = (char) (RAM[0x8200+i-2] & 0x0f);
	
				fclose(f);
			}
	
			return 1;
		}
		else return 0;	/* we can't load the hi scores yet */
	} };
	
	
	
	static HiscoreSavePtr hisave = new HiscoreSavePtr() { public void handler(String name)
	{
		FILE f;
	
	
		if ((f = fopen(name, "wb")) != null)
		{
			fwrite(RAM, 0x8200, 1, 6+6*5, f);
			fclose(f);
		}
	} };
	
	
	
	public static GameDriver popeyebl_driver = new GameDriver
	(
                "Popeye (bootleg)",
		"popeyebl",
                "MARC LAFONTAINE\nNICOLA SALMORIA",
		machine_driver,
	
		popeyebl_rom,
		null, null,
		null,
	
		input_ports,null, trak_ports, dsw, keys,
	
		color_prom, null, null,
		ORIENTATION_DEFAULT,

	
		hiload, hisave
	);
}
